<template>
  <el-dialog
    v-model="visible"
    title="上传文件"
    width="600px"
    @close="handleClose"
  >
    <div class="upload-container">
      <el-upload
        ref="uploadRef"
        class="upload-dragger"
        drag
        multiple
        :auto-upload="false"
        :on-change="handleFileChange"
        :on-remove="handleFileRemove"
        accept="video/*,audio/*"
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            支持视频和音频文件，单个文件大小不超过 500MB
          </div>
        </template>
      </el-upload>

      <!-- 上传列表 -->
      <div v-if="uploadTasks.length > 0" class="upload-list">
        <h4>上传队列</h4>
        <div
          v-for="task in uploadTasks"
          :key="task.id"
          class="upload-item"
        >
          <div class="upload-info">
            <div class="file-name">{{ task.name }}</div>
            <div class="file-size">{{ formatFileSize(task.file.size) }}</div>
          </div>
          
          <div class="upload-progress">
            <el-progress
              :percentage="task.progress"
              :status="task.status === 'error' ? 'exception' : task.status === 'completed' ? 'success' : undefined"
            />
            <div class="upload-status">
              {{ getStatusText(task.status) }}
            </div>
          </div>
          
          <div class="upload-actions">
            <el-button
              v-if="task.status === 'waiting'"
              size="small"
              type="danger"
              @click="removeTask(task.id)"
            >
              移除
            </el-button>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button
          type="primary"
          :disabled="uploadTasks.length === 0 || isUploading"
          @click="startUpload"
        >
          {{ isUploading ? '上传中...' : '开始上传' }}
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import type { UploadTask } from '@/types'

interface Props {
  modelValue: boolean
}

interface Emits {
  (e: 'update:modelValue', value: boolean): void
  (e: 'uploaded'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const uploadRef = ref()
const uploadTasks = ref<UploadTask[]>([])
const isUploading = ref(false)

const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 获取状态文本
const getStatusText = (status: string): string => {
  const statusMap: Record<string, string> = {
    waiting: '等待上传',
    uploading: '上传中',
    processing: '处理中',
    completed: '已完成',
    error: '上传失败'
  }
  return statusMap[status] || status
}

// 文件选择
const handleFileChange = (file: any) => {
  // 检查文件大小
  if (file.size > 500 * 1024 * 1024) {
    ElMessage.error('文件大小不能超过 500MB')
    return false
  }

  // 检查文件类型
  const isValidType = file.type.startsWith('video/') || file.type.startsWith('audio/')
  if (!isValidType) {
    ElMessage.error('只支持视频和音频文件')
    return false
  }

  const task: UploadTask = {
    id: Date.now().toString(),
    file: file.raw,
    name: file.name,
    progress: 0,
    status: 'waiting'
  }

  uploadTasks.value.push(task)
}

// 移除文件
const handleFileRemove = (file: any) => {
  const index = uploadTasks.value.findIndex(task => task.file === file.raw)
  if (index > -1) {
    uploadTasks.value.splice(index, 1)
  }
}

// 移除任务
const removeTask = (id: string) => {
  const index = uploadTasks.value.findIndex(task => task.id === id)
  if (index > -1) {
    uploadTasks.value.splice(index, 1)
  }
}

// 模拟上传进度
const simulateUpload = (task: UploadTask): Promise<void> => {
  return new Promise((resolve, reject) => {
    task.status = 'uploading'
    
    const interval = setInterval(() => {
      task.progress += Math.random() * 20
      
      if (task.progress >= 100) {
        task.progress = 100
        task.status = 'processing'
        clearInterval(interval)
        
        // 模拟处理时间
        setTimeout(() => {
          if (Math.random() > 0.1) { // 90% 成功率
            task.status = 'completed'
            resolve()
          } else {
            task.status = 'error'
            task.error = '上传失败'
            reject(new Error('上传失败'))
          }
        }, 1000)
      }
    }, 200)
  })
}

// 开始上传
const startUpload = async () => {
  if (uploadTasks.value.length === 0) return
  
  isUploading.value = true
  
  try {
    // 并发上传
    const promises = uploadTasks.value
      .filter(task => task.status === 'waiting')
      .map(task => simulateUpload(task))
    
    await Promise.allSettled(promises)
    
    const completedCount = uploadTasks.value.filter(task => task.status === 'completed').length
    const errorCount = uploadTasks.value.filter(task => task.status === 'error').length
    
    if (completedCount > 0) {
      ElMessage.success(`成功上传 ${completedCount} 个文件`)
      emit('uploaded')
    }
    
    if (errorCount > 0) {
      ElMessage.warning(`${errorCount} 个文件上传失败`)
    }
    
  } catch (error) {
    ElMessage.error('上传过程中发生错误')
  } finally {
    isUploading.value = false
  }
}

// 关闭对话框
const handleClose = () => {
  if (!isUploading.value) {
    uploadTasks.value = []
    uploadRef.value?.clearFiles()
  }
  visible.value = false
}
</script>

<style scoped>
.upload-container {
  padding: 0;
}

.upload-dragger {
  margin-bottom: 20px;
}

.upload-list {
  max-height: 300px;
  overflow-y: auto;
}

.upload-item {
  display: flex;
  align-items: center;
  padding: 12px;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  margin-bottom: 8px;
}

.upload-info {
  flex: 1;
  margin-right: 16px;
}

.file-name {
  font-weight: 500;
  margin-bottom: 4px;
}

.file-size {
  font-size: 12px;
  color: #666;
}

.upload-progress {
  flex: 2;
  margin-right: 16px;
}

.upload-status {
  font-size: 12px;
  color: #666;
  margin-top: 4px;
}

.upload-actions {
  flex: 0 0 auto;
}
</style> 